/******************************************************************************
This file is part of AppKit.
Project: appkit
Author : FergusZeng
Email  : cblock@126.com
git	   : https://gitee.com/newgolo/appkit.git
*******************************************************************************
MIT License

Copyright (c) 2022 cblock@126.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#pragma once

#include <string>
#include <vector>

#include "appkit/basetype.h"
/**
 * @file network.h
 * @brief 网络工具
 */
namespace appkit {

/**
 * @enum  NetHwState
 * @brief 网络硬件状态
 */
enum class NetHwState {
    Down, /**< 网口已被ifconfig down */
    Up,   /**< 网口已被ifconfig up */
    Error
};

/**
 * @enum  NetLinkState
 * @brief 网络连接状态
 */
enum class NetLinkState {
    Disconnected, /**< 网口未插入网线,link down */
    Connected,    /**< 网口已插入网线,link up */
    Error
};

/**
 *  @class  NetUtil
 *  @brief  网络工具类,提供对网络设别的常用操作.
 */
class NetUtil {
public:
    NetUtil();
    ~NetUtil();
    /**
     * @brief 判断是否是合法IP
     * @param ip
     * @return true
     * @return false
     */
    static bool isValidIP(const std::string& ip);
    /**
     * @brief 校验子网IP
     * @param gatewayIP
     * @param subnetMask
     * @param subnetIP
     * @return true
     * @return false
     */
    static bool checkSubnetIP(const std::string& gatewayIP,
                              const std::string& subnetMask,
                              std::string* subnetIP);
    /**
     * @brief 获取子网IP
     * @param gatewayIP
     * @param subnetMask
     * @param subIndex
     * @return std::string
     */
    static std::string getSubnetIP(const std::string& gatewayIP,
                                   const std::string& subnetMask, int subIndex);

    /**
     * @brief 获取网卡列表
     * @return std::vector<std::string>
     */
    static std::vector<std::string> getInterfaces();
    /**
     *  @brief  获取网口ip地址
     *  @param  intf 网口名称,如eth0
     *  @return std::string IP地址字符串,获取失败返回空字符串
     */
    static std::string getInetAddr(const std::string& intf);
    /**
     *  @brief  获取网口子网掩码地址
     *  @param  intf 网口名称,如eth0
     *  @return std::string IP地址字符串,获取失败返回空字符串
     */
    static std::string getMaskAddr(const std::string& intf);
    /**
     *  @brief  获取网口mac地址
     *  @param  intf 网口名称,如eth0
     *  @return std::vector<uint8> mac地址数组,获取失败返回空数组
     */
    static std::vector<uint8> getMacAddr(const std::string& intf);
    /**
     *  @brief  获取网口状态
     *  @param  intf 网口名称,如eth0
     *  @return NetHwState 成功返回网口状态
     */
    static NetHwState getHwState(const std::string& intf);
    /**
     *  @brief  获取网络连接状态
     *  @param  intf 网口名称,如eth0
     *  @return NetLinkState 成功返回网口状态
     */
    static NetLinkState getLinkState(const std::string& intf);
    /**
     * @brief 设置网口IP
     * @param intf
     * @param ipaddr
     * @return true
     * @return false
     */
    static bool setInetAddr(const std::string& intf, const std::string& ipaddr);
    /**
     * @brief 设置子网掩码
     * @param intf
     * @param netmask
     * @return true
     * @return false
     */
    static bool setMaskAddr(const std::string& intf,
                            const std::string& netmask);
    /**
     * @brief 设置MAC地址
     * @param intf
     * @param mac
     * @return true
     * @return false
     */
    static bool setMacAddr(const std::string& intf, const std::string& mac);
    /**
     * @brief 设置网口状态
     * @param intf
     * @param state
     * @return true
     * @return false
     */
    static bool setHwState(const std::string& intf, NetHwState state);

    /**
     * @brief 获取域名对应的IP
     * @param hostName 主机域名
     * @return std::string IP地址(如果域名带端口号,端口号一并返回)
     */
    static std::string getHostIP(const std::string& hostName);
};
}  // namespace appkit
